package com.yangxf.b_processDfinition;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.io.FileUtils;
import org.junit.Test;

public class ProcessDefinitionTest {

	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	/**
	 * 部署流程定义（从classpath）
	 */
	@Test
	public void deploymentProcessDefinition() {
		
		//这行代码暗中操作了数据库
		Deployment deployment = processEngine.getRepositoryService() // 与流程定义和部署相关的service
			.createDeployment() // 创建一个部署对象
			.name("流程定义")
			.addClasspathResource("diagrams/helloworld.bpmn") // 从类路径中加载，一次加载一个
			.addClasspathResource("diagrams/helloworld.png")
			.deploy(); // 完成部署
		
		System.out.println(deployment.getId());
		System.out.println(deployment.getName());
	}
	
	/**
	 * 部署流程（从zip文件）
	 */
	@Test
	public void deploymentProcessDefinitionZip() {
		InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/helloword.zip");
		ZipInputStream zipInputStream = new ZipInputStream(in);
		//这行代码暗中操作了数据库
		Deployment deployment = processEngine.getRepositoryService() // 与流程定义和部署相关的service
			.createDeployment() // 创建一个部署对象
			.name("流程定义")
			.addZipInputStream(zipInputStream) // zip格式文件完成部署
			.deploy(); // 完成部署
		
		System.out.println(deployment.getId());
		System.out.println(deployment.getName());
	}
	
	/**
	 * 查询流程定义
	 */
	@Test
	public void queryProcessDefinition() {
		List<ProcessDefinition> list = (List<ProcessDefinition>) processEngine.getRepositoryService() // 与流程定义和部署对象相关的service
			.createProcessDefinitionQuery() // 创建流程定义查询
//			.deploymentId(deploymentId); // 指定查询条件，使用部署对象id查询
//			.processDefinitionId(processDefinitionId); // 使用流程定义id查询
//			.processDefinitionKey(processDefinitionKey); // 使用流程定义key查询
//			.processDefinitionNameLike(processDefinitionNameLike); // 流程定义名称模糊查询
//			.list(); // 流程定义列表
//			.singleResult(); // 返回唯一结果集
//			.count(); // 返回结果集数量
//			.listPage(firstResult, maxResults); // 分页查询
			.orderByProcessDefinitionVersion().asc() // 按照版本升序排列
			.list();
//			.orderByProcessDefinitionName().desc(); // 按照流程定义名称降序排列
			if(list!=null && list.size()>0) {
				for(ProcessDefinition pd : list) {
					System.out.println(pd.getId());
					System.out.println(pd.getName());
				}
			}
	}
	
	/**
	 * 删除流程定义
	 */
	@Test
	public void deleteProcessDefinition() {
		
		String deploymentId = "5001";
		// 只能删除未启动流程
//		processEngine.getRepositoryService() // 流程定义相关service
//			.deleteDeployment(deploymentId);
		
		// 级联删除
		processEngine.getRepositoryService() // 流程定义相关service
			.deleteDeployment(deploymentId, true);
	}
	
	/**
	 * 查看流程图
	 */
	@Test
	public void queryView() {
		
		String deploymentId = "2501";
		
		List<String> names = processEngine.getRepositoryService()
			.getDeploymentResourceNames(deploymentId); // 获取指定部署下所有文件的名称
		
		String resourceName = "";
		
		if(names!=null && names.size()>0) {
			for(String name : names) {
				if(name.indexOf(".png") >= 0) {
					resourceName = name;
				}
			}
		}
		
		//生成图片流输出到文件夹下
		InputStream in = processEngine.getRepositoryService()
			.getResourceAsStream(deploymentId, resourceName);
		
		//将图片生成到指定目录
		File file = new File("d:/" + resourceName);
		
		//输入流的图片写到d盘
		try {
			FileUtils.copyInputStreamToFile(in, file);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 查询最新版本的流程定义
	 * 
	 */
	@Test
	public void lastVersionProcessDefinition() {
		
		List<ProcessDefinition> list = processEngine.getRepositoryService() // 流程部署service
			.createProcessDefinitionQuery() // 创建流程定义查询
			.orderByProcessDefinitionVersion().asc() //
			.list();
		
		Map<String,ProcessDefinition> map = new LinkedHashMap<String,ProcessDefinition>();
		if(list!=null && list.size()>0) {
			for(ProcessDefinition pd:list) {
				map.put(pd.getKey(), pd);
			}
		}
		
		List<ProcessDefinition> pdList = new ArrayList<ProcessDefinition>(map.values());
		
		if(pdList!=null && pdList.size()>0) {
			for(ProcessDefinition pd : pdList) {
				System.out.println(pd.getId());
				System.out.println(pd.getName());
			}
		}
	}
	
	/**
	 * 删除流程定义，包括key相同的所有不同版本的流程定义
	 */
	@Test
	public void deleteProcessDefinitionByKey() {
		
		String processDefinitionKey ="helloworld";
		
		//使用流程定义的key查询流程定义，查出所有版本
		List<ProcessDefinition> list = processEngine.getRepositoryService() // 流程部署service
			.createProcessDefinitionQuery() // 创建 流程定义 查询
			.processDefinitionKey(processDefinitionKey) // 
			.list();
		
		if(list!=null && list.size()>0) {
			for(ProcessDefinition pd : list) {
				String deploymentId = pd.getDeploymentId();
				processEngine.getRepositoryService()
					.deleteDeployment(deploymentId, true); // 级联删除
			}
		}
	}
}
